home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 85 / CD Temático 40 Febrero 2004.iso / DOS / testdisk / src / fat_adv.c < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-09  |  49.6 KB  |  1,632 lines

  1. /*
  2.  
  3.     File: fat_adv.c
  4.  
  5.     Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
  6.   
  7.     This software is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.   
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.   
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>    /* toupper */
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <time.h>
  28. #include <sys/stat.h>
  29. #include "types.h"
  30. #include "common.h"
  31. #include "fat.h"
  32. #include "lang.h"
  33. #include "fnctdsk.h"
  34. #include "testdisk.h"
  35. #include "intrface.h"
  36. #include "dir.h"
  37. #include "fat_dir.h"
  38.  
  39.  
  40. typedef struct info_sector_cluster t_sector_cluster;
  41.  
  42. struct info_sector_cluster
  43. {
  44.   unsigned int sector;
  45.   unsigned int cluster;
  46. };
  47.  
  48. struct info_offset
  49. {
  50.   dword offset;
  51.   unsigned int nbr;
  52.   unsigned int fat_type;
  53. };
  54.  
  55. typedef struct info_offset t_info_offset;
  56.  
  57. typedef struct info_cluster_offset t_cluster_offset;
  58.  
  59. struct info_cluster_offset
  60. {
  61.   unsigned int cluster_size;
  62.   dword offset;
  63.   unsigned int nbr;
  64.   unsigned int first_sol;
  65. };
  66. static upart_type_t fat_find_info(t_param_disk *disk_car,unsigned int*reserved, unsigned int*fat_length, const t_diskext *partition,const dword max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int debug,const int dump_ind,const int interface);
  67. static int fat_find_type(t_param_disk *disk_car,const t_diskext *partition,const dword max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int debug,const int dump_ind,const int interface,unsigned int *nbr_offset,t_info_offset *info_offset);
  68.  
  69. static unsigned int fat_find_fat_start(const unsigned char *buffer,const int p_fat12, const int p_fat16, const int p_fat32,dword*fat_offset);
  70.  
  71. static int create_fat_boot_sector(t_param_disk *disk_car, t_diskext *partition, const unsigned int reserved, const int debug, const unsigned int dir_entries, const dword root_cluster, const unsigned int cluster_size, const unsigned int fat_length,const int interface, const upart_type_t upart_type);
  72. static unsigned int fat32_find_root_cluster(t_param_disk *disk_car,const t_diskext *partition,const unsigned int cluster_size, const dword no_of_cluster,const unsigned int offset, const int unsigned reserved,const int interface, const int debug);
  73. static int write_FAT_boot_code_aux(unsigned char *buffer);
  74. static int find_cluster_size(t_param_disk *disk_car, t_diskext *partition, const int debug, const int dump_ind,const int interface, unsigned int *cluster_size, dword *offset);
  75. static int find_dir_entries(t_param_disk *disk_car,const t_diskext *partition, const unsigned int offset,const int debug);
  76. static int find_cluster_size_aux(const t_sector_cluster *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *cluster_size, dword *offset, const int debug);
  77. static int analyse_dir_entries(t_param_disk *disk_car,const t_diskext *partition, const unsigned int offset, const int debug);
  78. static int analyse_dir_entries2(t_param_disk *disk_car,const t_diskext *partition, const unsigned int reserved, const unsigned int fat_length,const int debug, unsigned int root_size_max,const upart_type_t upart_type);
  79. static int calcul_cluster_size(const upart_type_t upart_type, const dword data_size, const unsigned int fat_length);
  80. static inline int check_entree(const unsigned char *entree);
  81.  
  82. /* The goal is to identify the begining of the two FAT
  83.  * TestDisk assumes that
  84.  * - fragmentation is low
  85.  * - free cluster are unusual in the beginning of a FAT 
  86.  * - small files are unsual at the beginning of a FAT
  87.  * If fragmentation, EOC(End Of Cluster) or free cluster, increments nb_frag.
  88.  * */
  89.  
  90. /* 
  91.  * 0 entree is free
  92.  * 1 entree is used
  93.  * 2 not an entry
  94.  * */
  95. static inline int check_entree(const unsigned char *entree)
  96. {
  97.   int i;
  98.   if((entree[0xB]&ATTR_EXT_MASK)==ATTR_EXT)
  99.     return 1;
  100. /* ecrit_rapport("check_entree %02x\n",*(entree+0)); */
  101.   if(entree[0]==0)
  102.   {
  103.     for(i=0;i<0x20;i++)
  104.       if(*(entree+i)!='\0')
  105.     return 2;
  106.     return 0;
  107.   }
  108.   if(entree[0]==0x20)
  109.     return 2;
  110.   if(entree[0]==0xE5)
  111.     return 1;
  112.   for(i=0;i<8+3;i++)
  113.   {
  114.     if((*(entree+i)>=0x06 && *(entree+i)<=0x1f)||
  115.       (*(entree+i)>=0x3a && *(entree+i)<=0x3f)||
  116.       (*(entree+i)>='a' && *(entree+i)<='z'))
  117.       return 2;
  118.     switch(*(entree+i))
  119.     {
  120.       case 0x1:
  121.       case 0x2:
  122.       case 0x3:
  123.       case 0x4:
  124.       case 0x22:
  125.       case 0x2A:
  126.       case 0x2B:
  127.       case 0x2C:
  128.       case 0x2E:
  129.       case 0x2F:
  130.       case 0x5B:
  131.       case 0x5C:
  132.       case 0x5D:
  133.       case 0x7C:
  134. /*ecrit_rapport("check_entree bad  %c (%02x)\n",*(entree+i),*(entree+i)); */
  135.     return 2;
  136.       default:
  137. /*ecrit_rapport("check_entree good %c (%02x)\n",*(entree+i),*(entree+i)); */
  138.     break;
  139.     }
  140.   }
  141.   return 1;
  142. }
  143.  
  144. /* */
  145.  
  146.  
  147. dword get_subdirectory(t_param_disk *disk_car,const dword hd_offset,const dword i)
  148. {
  149.   unsigned char buffer[SECTOR_SIZE];
  150.   if(disk_car->read(disk_car,1, &buffer, hd_offset))
  151.   {
  152.     ecrit_rapport(msg_ROOT_CLUSTER_RERR); return 1;
  153.   }
  154. /* dump(stdscr,buffer,SECTOR_SIZE); */
  155.   /*                     12345678123*/
  156.   if(strncmp(&buffer[0],".          ",8+3)!=0)
  157.     return 1;
  158.   if((unsigned)((buffer[0x15]<<24)|(buffer[0x14]<<16)|(buffer[0x1B]<<8)|buffer[0x1A])!=i)
  159.     return 1;
  160.   /*                        12345678123*/
  161.   if(strncmp(&buffer[0x20],"..         ",8+3)!=0)
  162.     return 1;
  163.   return (buffer[0x35]<<24)+(buffer[0x34]<<16)+(buffer[0x3B]<<8)+buffer[0x3A];
  164. }
  165.  
  166. static unsigned int fat32_find_root_cluster(t_param_disk *disk_car,const t_diskext *partition,const unsigned int cluster_size, const dword no_of_cluster,const unsigned int offset, const int unsigned reserved,const int interface, const int debug)
  167. {
  168.   if(debug)
  169.     ecrit_rapport("fat32_find_root_cluster(cluster_size=%u,no_of_cluster=%lu,offset=%u,reserved=%u)\n",cluster_size,no_of_cluster,offset,reserved);
  170.   if(cluster_size==0)
  171.     return 0;
  172.   {
  173.     dword root_cluster;
  174.     unsigned char buffer[cluster_size*SECTOR_SIZE];
  175.     int ind_stop=FALSE;
  176.     dword root_cluster_second_choice=0;
  177.     if(interface)
  178.     {
  179.       wmove(stdscr,22,0);
  180.       wstandout(stdscr);
  181.       waddstr(stdscr,"  Stop  ");
  182.       wstandend(stdscr);
  183.     }
  184.     for(root_cluster=2;(root_cluster<2+no_of_cluster)&&!ind_stop;root_cluster++)
  185.     {
  186.       if(interface&&(root_cluster%71)==0)
  187.       {
  188.     wmove(stdscr,9,0);
  189.     wclrtoeol(stdscr);
  190.     wdoprintf(stdscr,"Search root cluster %10lu/%lu",root_cluster,2+no_of_cluster);
  191.     wrefresh(stdscr);
  192.     switch(wgetch_nodelay(stdscr))
  193.     {
  194.       case KEY_ENTER:
  195. #ifdef PADENTER
  196.       case PADENTER:
  197. #endif
  198.       case '\n':
  199.       case '\r':
  200.       case 's':
  201.       case 'S':
  202.         ind_stop=1;
  203.         break;
  204.     }
  205.       }
  206.       /*
  207.        */
  208.       if(disk_car->read(disk_car,cluster_size, &buffer, partition->lba+offset+(root_cluster-2)*cluster_size)==0)
  209.       {
  210.     if(debug>1)
  211.       ecrit_rapport("fat32_find_root_cluster test cluster=%lu\n",root_cluster);
  212.     /*    dump(stdscr,buffer,SECTOR_SIZE); */
  213.     if(strncmp(&buffer[0],".          ",8+3)!=0)
  214.     {
  215.       unsigned int i,found=1;
  216.       int etat=0,nb_subdir=0,nb_subdir_ok=0;
  217.       for(i=0;found && (i<16*cluster_size);i++)
  218.       {
  219.         int res=check_entree(&buffer[i*0x20]);
  220.         if(debug>2)
  221.           ecrit_rapport("fat32_find_root_cluster root_cluster=%lu i=%u etat=%d res=%d\n",root_cluster,i,etat,res);
  222.         switch(res)
  223.         {
  224.           case 0:
  225.         if(etat==0)
  226.           etat=1;
  227.         break;
  228.           case 1:
  229.         if(etat==1)
  230.         {
  231.           etat=2;
  232.           found=0;
  233.         }
  234.         break;
  235.           case 2:
  236.         found=0;
  237.         break;
  238.         }
  239.         if((buffer[i*0x20]!=DELETED_FLAG) && (buffer[i*0x20+0xB]==ATTR_DIR)) /* Test directory */
  240.         {
  241.           nb_subdir++;
  242.           /*      ecrit_rapport("directory %s\n",&buffer[i*0x20]); */
  243.         }
  244.       }
  245.       for(i=0;found && (i<16*cluster_size);i++)
  246.       {
  247.         if((buffer[i*0x20]!=DELETED_FLAG) && (buffer[i*0x20+0xB]==ATTR_DIR)) /* Test directory */
  248.         {
  249.           dword cluster=(buffer[i*0x20+0x15]<<24)+(buffer[i*0x20+0x14]<<16)+
  250.         (buffer[i*0x20+0x1B]<<8)+buffer[i*0x20+0x1A];
  251.           /*      ecrit_rapport("cluster %ld\n",cluster); */
  252.           if((cluster>2+no_of_cluster)||(get_subdirectory(disk_car,partition->lba+offset+(cluster-2)*cluster_size,cluster)!=0))
  253.           {
  254.         /*        if(debug) */
  255.         /*          ecrit_rapport("failed with %s\n",&buffer[i*0x20]); */
  256.           }
  257.           else
  258.         nb_subdir_ok++;
  259.         }
  260.       }
  261.       if(found)
  262.       {
  263.         if((nb_subdir_ok>nb_subdir*0.90)&&(nb_subdir>=3))
  264.         {
  265.           dword tmp=root_cluster;
  266.           int back=0;    /* To avoid an endless loop... */
  267.           /* Il faut ajouter un parcours arriere de la FAT 
  268.            * car on localise le dernier cluster du root_cluster */
  269.           if(debug)
  270.         ecrit_rapport("cluster %lu, etat=%d, found=%d,nb_subdir=%d,nb_subdir_ok=%d\n",root_cluster,etat,found,nb_subdir,nb_subdir_ok);
  271.           do
  272.           {
  273.         root_cluster=tmp;
  274.         tmp=fat32_get_prev_cluster(disk_car,partition,reserved,root_cluster,no_of_cluster);
  275.         if(debug)
  276.           ecrit_rapport("prev cluster(%lu)=>%lu\n",root_cluster,tmp);
  277.         if(tmp)
  278.         {
  279.           /* Check cluster number */
  280.           if((tmp<2) || (tmp>=2+no_of_cluster))
  281.           {
  282.             ecrit_rapport("bad cluster number\n");
  283.             return root_cluster;
  284.           }
  285.           /* Read the cluster */
  286.           if(disk_car->read(disk_car,cluster_size, &buffer, partition->lba+offset+(tmp-2)*cluster_size)!=0)
  287.           {
  288.             ecrit_rapport("cluster can't be read\n");
  289.             return root_cluster;
  290.           }
  291.           /* Check if this cluster is a directory structure. FAT can be damaged */
  292.           for(i=0;i<16*cluster_size;i++)
  293.           {
  294.             if(check_entree(&buffer[i*0x20])!=1)
  295.             {
  296.               ecrit_rapport("cluster data is not a directory structure\n");
  297.               return root_cluster;
  298.             }
  299.           }
  300.         }
  301.           } while(tmp && (++back<10));
  302.           return root_cluster;
  303.         }
  304.         {
  305.           t_file_data *dir_list;
  306.           t_dir_data dir_data;
  307.           WINDOW *window=newwin(0,0,0,0);    /* full screen */
  308.           if(root_cluster_second_choice==0)
  309.         root_cluster_second_choice=root_cluster;
  310.           if(debug)
  311.         ecrit_rapport("Potential root_cluster %lu\n",root_cluster);
  312.           dir_list=dir_fat_aux(buffer,SECTOR_SIZE*cluster_size,cluster_size);
  313.           aff_copy(window);
  314.           dir_data.window=window;
  315.           dir_data.debug=debug;
  316.           dir_data.private_dir_data=NULL;
  317.           dir_data.get_dir=fat32_dir;
  318.           strncpy(dir_data.current_directory,"/",sizeof(dir_data.current_directory));
  319.           dir_aff(disk_car,partition,&dir_data,dir_list,root_cluster);
  320.           delete_list_file(dir_list);
  321.           delwin(window);
  322. #ifdef DJGPP
  323.           wredrawln(stdscr,0,stdscr->_maxy);    /* redrawwin def is boggus in pdcur24 */
  324. #else
  325.           redrawwin(stdscr);    /* stdscr has been corrupted by window */
  326. #endif
  327.           if(ask_confirmation("Root directory found ? [Y/N] "))
  328.           {
  329.         return root_cluster;
  330.           }
  331.         }
  332.       }
  333.     }
  334.     else
  335.     { /* Directory found */
  336.       dword cluster=(buffer[1*0x20+0x15]<<24)+(buffer[1*0x20+0x14]<<16)+
  337.         (buffer[1*0x20+0x1B]<<8)+buffer[1*0x20+0x1A];
  338.       if((memcmp(&buffer[0x20],"..         ",8+3)==0) &&
  339.           (buffer[1*0x20+0xB]==ATTR_DIR)&&(cluster==0)) /* First-level directory */
  340.       {
  341.         ecrit_rapport("First-level directory found at cluster %lu\n",root_cluster);
  342.       }
  343.     }
  344.       }
  345.     }
  346.     ecrit_rapport("Search root cluster stopped: %10lu/%lu\n",root_cluster,no_of_cluster);
  347.   }
  348.   return 0;
  349. }
  350.  
  351. static int find_dir_entries(t_param_disk *disk_car,const t_diskext *partition, const unsigned int offset,const int debug)
  352. {
  353.   unsigned char buffer[SECTOR_SIZE];
  354.   unsigned int i,j;
  355.   int etat=0;
  356.   int sector_etat0=0;
  357.   dword hd_offset;
  358.   hd_offset=partition->lba+offset;
  359.   for(i=0;(i<200)&&(etat!=2)&&(i<offset);i++)
  360.   {
  361.     if(disk_car->read(disk_car,1, &buffer, hd_offset)!=0)
  362.     {
  363.       ecrit_rapport("dir_entries: read error, dir_entries>=%u (%u sectors)\n",i*16,i);
  364. /*     return 0; */
  365.     }
  366.     else
  367.     {
  368.       for(j=15;j>0;j--)
  369.       {
  370.     if(debug>1)
  371.     {
  372.       ecrit_rapport("find_dir_entries sector=%u entree=%d etat=%d\n",offset-i,j,etat);
  373.     }
  374.     if(etat==0)
  375.     {
  376.       switch(check_entree(&buffer[j*0x20]))
  377.       {
  378.         case 0:
  379.           break;
  380.         case 1:
  381.           sector_etat0=i;
  382.           etat=1;
  383.           break;
  384.         case 2:
  385.           return 0;
  386.       }
  387.     } else {
  388.       switch(check_entree(&buffer[j*0x20]))
  389.       {
  390.         case 1:
  391.           etat=1;
  392.           break;
  393.         case 0:
  394.         case 2:
  395.           return (i-1)*16;
  396.       }
  397.     }
  398.       }
  399.     }
  400.     hd_offset--;
  401.   }
  402.   if((i==200) || (i==offset))
  403.     return 0;
  404.   return (i-1)*16;
  405. }
  406.  
  407. static int analyse_dir_entries(t_param_disk *disk_car,const t_diskext *partition, const unsigned int offset,const int debug)
  408. {
  409.   unsigned char buffer[SECTOR_SIZE];
  410.   int i,j;
  411.   int etat=0;
  412.   int sector_etat1=0;
  413.   dword hd_offset;
  414.   hd_offset=partition->lba+offset;
  415.   for(i=0;(i<200)&&(etat!=2);i++)
  416.   {
  417.     if(disk_car->read(disk_car,1, &buffer, hd_offset)!=0)
  418.     {
  419.       ecrit_rapport("dir_entries: read error, dir_entries>=%u (%u sectors)\n",i*16,i);
  420. /*     return 0; */
  421.     }
  422.     else
  423.     {
  424.       for(j=0;j<16;j++)
  425.       {
  426.     if(check_entree(&buffer[j*0x20])==0)
  427.     {
  428.       if(etat==0)
  429.       {
  430.         if(i*16+j>0)
  431.         {
  432.           etat=1;
  433.           sector_etat1=i;
  434.           if(debug>0)
  435.         ecrit_rapport("dir_entries 0->1 %d\n",i*16+j);
  436.         } else {
  437.           return 0;
  438.         }
  439.       }
  440.     }
  441.     else
  442.       if(etat==1)
  443.       {
  444.         if(i==sector_etat1)
  445.         {
  446.           return 0;
  447.         } else {
  448.           etat=2;
  449.           if(debug>0)
  450.         ecrit_rapport("dir_entries 1->2 %d\n",i*16+j);
  451.         }
  452.       }
  453.       }
  454.     }
  455.     hd_offset++;
  456.   }
  457.   if(i==200)
  458.     return 0;
  459.   return (i-1)*16;
  460. }
  461.  
  462. static int analyse_dir_entries2(t_param_disk *disk_car,const t_diskext *partition, const unsigned int reserved, const unsigned int fat_length,const int debug, unsigned int root_size_max,const upart_type_t upart_type)
  463. {
  464.   t_file_data *current_file;
  465.   t_file_data *dir_list=NULL;
  466.   unsigned int nbr_sector;
  467.   unsigned char *buffer_dir;
  468.   if(root_size_max==0)
  469.   {
  470.     root_size_max=4096;
  471.   }
  472.   nbr_sector=(root_size_max+16-1)/16;
  473.   buffer_dir=(unsigned char *)MALLOC(SECTOR_SIZE*nbr_sector);
  474.   if(disk_car->read(disk_car, nbr_sector, buffer_dir, partition->lba+reserved+2*fat_length)!=0)
  475.   {
  476.     ecrit_rapport("FAT 1x");
  477.     ecrit_rapport(msg_ROOT_CLUSTER_RERR);
  478.     return 0;
  479.   }
  480.   {
  481.     dword start_data=reserved+2*fat_length+(root_size_max+16-1)/16;
  482.     unsigned int cluster_size=calcul_cluster_size(upart_type,partition->part_size-start_data,fat_length);
  483.     dir_list=dir_fat_aux(buffer_dir,SECTOR_SIZE*nbr_sector,cluster_size);
  484.   }
  485.   if(debug>1)
  486.   {
  487.     dir_aff_log(disk_car, partition, NULL, dir_list);
  488.   }
  489.   for(current_file=dir_list;(current_file!=NULL)&&(LINUX_S_ISDIR(current_file->filestat.st_mode)==0);current_file=current_file->next);
  490.   if(current_file!=NULL)
  491.   {
  492.     unsigned long int new_inode=current_file->filestat.st_ino;
  493.     unsigned int dir_entries;
  494.     if(debug>1)
  495.     {
  496.       ecrit_rapport("Directory %s used inode=%lu\n",current_file->name,new_inode);
  497.     }
  498.     for(dir_entries=16;dir_entries<=root_size_max;dir_entries+=16)
  499.     {
  500.       dword start_data=reserved+2*fat_length+(dir_entries+16-1)/16;
  501.       unsigned int cluster_size=calcul_cluster_size(upart_type,partition->part_size-start_data,fat_length);
  502.       if(debug>1)
  503.       {
  504.     ecrit_rapport("dir_entries %u, cluster_size %u\n",dir_entries,cluster_size);
  505.       }
  506.       if(disk_car->read(disk_car, 1, buffer_dir, partition->lba+start_data+(new_inode-2)*cluster_size)==0)
  507.       {
  508.     if((memcmp(&buffer_dir[0],".          ",8+3)==0)&&(memcmp(&buffer_dir[0x20],"..         ",8+3)==0))
  509.     {
  510.       dword cluster=(buffer_dir[0*0x20+0x15]<<24)+(buffer_dir[0*0x20+0x14]<<16)+
  511.         (buffer_dir[0*0x20+0x1B]<<8)+buffer_dir[0*0x20+0x1A];
  512.       dword cluster_prev=(buffer_dir[1*0x20+0x15]<<24)+(buffer_dir[1*0x20+0x14]<<16)+
  513.         (buffer_dir[1*0x20+0x1B]<<8)+buffer_dir[1*0x20+0x1A];
  514.       if(debug>1)
  515.       {
  516.         ecrit_rapport("Cluster %lu, directory .. found link to %lu\n",cluster,cluster_prev);
  517.       }
  518.       if(cluster_prev==0 && cluster==new_inode)
  519.       {
  520.         FREE(buffer_dir);
  521.         delete_list_file(dir_list);
  522.         return ((dir_entries+16-1)/16)*16;
  523.       }
  524.     }
  525.       }
  526.     }
  527.   }
  528.   else
  529.   {
  530.     ecrit_rapport("No directory found\n");
  531.   }
  532.   FREE(buffer_dir);
  533.   delete_list_file(dir_list);
  534.   return root_size_max;
  535. }
  536.  
  537. static int create_fat_boot_sector(t_param_disk *disk_car, t_diskext *partition, const unsigned int reserved, const int debug, const unsigned int dir_entries, const dword root_cluster, const unsigned int cluster_size, const unsigned int fat_length,const int interface, const upart_type_t upart_type)
  538. {
  539.   unsigned char orgboot[3*SECTOR_SIZE];
  540.   unsigned char newboot[3*SECTOR_SIZE];
  541.   struct fat_boot_sector *org_fat_header=(struct fat_boot_sector *)&orgboot;
  542.   struct fat_boot_sector *fat_header=(struct fat_boot_sector *)&newboot;
  543.   int error=0;
  544.   dword part_size=0;
  545.   if(disk_car->read(disk_car,3, &orgboot, partition->lba))
  546.   {
  547.     ecrit_rapport("create_fat_boot_sector: Can't read old boot sector\n");
  548.     memset(&orgboot,0,3*SECTOR_SIZE);
  549.   }
  550.   memcpy(&newboot,&orgboot,3*SECTOR_SIZE);
  551.   if((le16(fat_header->marker)!=0xAA55)||
  552.       !((fat_header->ignored[0]==0xeb && fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9))
  553.   {
  554.     write_FAT_boot_code_aux(newboot);
  555.   }
  556.   fat_header->sector_size[0]=SECTOR_SIZE & 0xFF;
  557.   fat_header->sector_size[1]=SECTOR_SIZE>>8;
  558.   fat_header->fats=2;
  559.   fat_header->media=0xF8;
  560.   fat_header->secs_track=disk_car->CHS.sector;
  561.   fat_header->heads=disk_car->CHS.head+1;
  562.   fat_header->marker=le16(0xAA55);
  563.   if(!((fat_header->ignored[0]==0xeb&&fat_header->ignored[2]==0x90)||fat_header->ignored[0]==0xe9))
  564.   {
  565.     fat_header->ignored[0]=0xeb;
  566.     fat_header->ignored[2]=0x90;
  567.   }
  568.  
  569.   /* I have seen a FAT32 partition that Win98 2nd edition was unable to read
  570.    * because this name was missing! */
  571.   if(memcmp(fat_header->system_id,"MSDOS5.0",8) &&
  572.       memcmp(fat_header->system_id,"MSWIN4.0",8) &&
  573.       memcmp(fat_header->system_id,"MSWIN4.1",8))
  574.     memcpy(fat_header->system_id,"MSWIN4.1",8);
  575.   
  576.   if(partition->status==STATUS_LOG)
  577.     fat_header->hidden=le32(63);
  578.   else
  579.     fat_header->hidden=le32(partition->lba);
  580.   fat_header->cluster_size=cluster_size;
  581.   fat_header->reserved=le16(reserved);
  582.   /* The filesystem size can be smaller than the partition size */
  583.   switch(upart_type)
  584.   {
  585.     case UP_FAT12:
  586.       part_size=le16(fat_header->reserved)+2*fat_length+dir_entries*32/SECTOR_SIZE+cluster_size*(fat_length*SECTOR_SIZE*2/3-2);
  587.       break;
  588.     case UP_FAT16:
  589.       part_size=le16(fat_header->reserved)+2*fat_length+dir_entries*32/SECTOR_SIZE+cluster_size*(fat_length*SECTOR_SIZE/2-2);
  590.       break;
  591.     case UP_FAT32:
  592.       part_size=le16(fat_header->reserved)+2*fat_length+cluster_size*(fat_length*SECTOR_SIZE/4-2);
  593.       break;
  594.     default:
  595.       ecrit_rapport("create_fat_boot_sector: severe error\n");
  596.       exit(1);
  597.   }
  598.   if(part_size>partition->part_size)
  599.     part_size=partition->part_size;
  600.   if(part_size>0xFFFF)
  601.   {
  602.     fat_header->sectors[0]=0;
  603.     fat_header->sectors[1]=0;
  604.     fat_header->total_sect=le32(part_size);
  605.   }
  606.   else
  607.   {
  608.     fat_header->sectors[1]=part_size>>8;
  609.     fat_header->sectors[0]=part_size;
  610.     fat_header->total_sect=le32(0);
  611.   }
  612.   switch(upart_type)
  613.   {
  614.     case UP_FAT12:
  615.       if((fat_length==0) || (dir_entries==0))
  616.     error=1;
  617.       if((newboot[36]<0x80)||(newboot[36]>0x88))
  618.     newboot[36]=0x80; /* BS_DrvNum=0x80 */
  619.       newboot[37]=0;    /* BS_Reserved1=0 */
  620.       newboot[38]=0x29;     /* Boot sig=0x29 */
  621.       if(memcmp(newboot+FAT_NAME2,"FAT32",5)==0)
  622.     memcpy(newboot+FAT_NAME2, "        ",8);
  623.       memcpy(newboot+FAT_NAME1,"FAT12   ",8);
  624.       fat_header->fat_length=le16(fat_length);
  625.       fat_header->dir_entries[1]=dir_entries>>8;
  626.       fat_header->dir_entries[0]=dir_entries;
  627.       if(check_volume_name(&newboot[FAT1X_PART_NAME],11))
  628.     newboot[FAT1X_PART_NAME]='\0';
  629.       break;
  630.     case UP_FAT16:
  631.       if((fat_length==0) || (dir_entries==0))
  632.     error=1;
  633.       if((newboot[36]<0x80)||(newboot[36]>0x88))
  634.     newboot[36]=0x80; /* BS_DrvNum */
  635.       newboot[37]=0;    /* BS_Reserved1=0 */
  636.       newboot[38]=0x29;     /* Boot sig=0x29 */
  637.       if(memcmp(newboot+FAT_NAME2,"FAT32",5)==0)
  638.     memcpy(newboot+FAT_NAME2, "        ",8);
  639.       memcpy(newboot+FAT_NAME1,"FAT16   ",8);
  640.       fat_header->fat_length=le16(fat_length);
  641.       fat_header->dir_entries[1]=dir_entries>>8;
  642.       fat_header->dir_entries[0]=dir_entries;
  643.       if(check_volume_name(&newboot[FAT1X_PART_NAME],11))
  644.     newboot[FAT1X_PART_NAME]='\0';
  645.       break;
  646.     case UP_FAT32:
  647.       if((fat_length==0) || (root_cluster==0))
  648.     error=1;
  649.       fat_header->fat_length=le16(0);
  650.       fat_header->dir_entries[0]=0;
  651.       fat_header->dir_entries[1]=0;
  652.       fat_header->fat32_length=le32(fat_length);
  653.       /*
  654.      Bits 0-3 -- Zero-based number of active FAT. Only valid if mirroring
  655.      is disabled.
  656.      Bits 4-6 -- Reserved.
  657.      Bit    7 -- 0 means the FAT is mirrored at runtime into all FATs.
  658.      -- 1 means only one FAT is active; it is the one referenced
  659.      in bits 0-3.
  660.      Bits 8-15 -- Reserved.
  661.        */
  662.       fat_header->flags=le16(0);
  663.       fat_header->version[0]=0;
  664.       fat_header->version[1]=0;
  665.       fat_header->root_cluster=le32(root_cluster);
  666.       /* Sector number of FSINFO structure in the reserved area of the FAT32 volume. */
  667.       fat_header->info_sector=le16(1);
  668.       fat_header->backup_boot=le16(6);
  669.       memset(&fat_header->BPB_Reserved,0,sizeof(fat_header->BPB_Reserved));
  670.       if((fat_header->BS_DrvNum<0x80)||(fat_header->BS_DrvNum>0x87))
  671.     fat_header->BS_DrvNum=0x80;
  672.       fat_header->BS_Reserved1=0;
  673.       fat_header->BS_BootSig=0x29;
  674.       if((memcmp(newboot+FAT_NAME1,"FAT12",5)==0) ||(memcmp(newboot+FAT_NAME1,"FAT16",5)==0))
  675.     memcpy(newboot+FAT_NAME1,"        ",8);
  676.       memcpy(fat_header->BS_FilSysType,  "FAT32   ",8);
  677.       newboot[0x1FC]=0x00;    /* part of the signature */
  678.       newboot[0x1FD]=0x00;
  679.       memset(&newboot[SECTOR_SIZE],0,SECTOR_SIZE);
  680.       newboot[SECTOR_SIZE]='R';        /* Signature RRaA */
  681.       newboot[SECTOR_SIZE+1]='R';
  682.       newboot[SECTOR_SIZE+2]='a';
  683.       newboot[SECTOR_SIZE+3]='A';
  684.       newboot[SECTOR_SIZE+0x1E4]='r';        /* Signature rrAa */
  685.       newboot[SECTOR_SIZE+0x1E5]='r';
  686.       newboot[SECTOR_SIZE+0x1E6]='A';
  687.       newboot[SECTOR_SIZE+0x1E7]='a';
  688.       /* Don't set the number of free cluster or the next free cluster */
  689.       newboot[SECTOR_SIZE+0x1E8]=0xFF;    /* Free clusters on disk */
  690.       newboot[SECTOR_SIZE+0x1E9]=0xFF;
  691.       newboot[SECTOR_SIZE+0x1EA]=0xFF;
  692.       newboot[SECTOR_SIZE+0x1EB]=0xFF;
  693.       newboot[SECTOR_SIZE+0x1EC]=0xFF;    /* Next avaible clusters */
  694.       newboot[SECTOR_SIZE+0x1ED]=0xFF;
  695.       newboot[SECTOR_SIZE+0x1EE]=0xFF;
  696.       newboot[SECTOR_SIZE+0x1EF]=0xFF;
  697.       newboot[SECTOR_SIZE+0x1FC]=0x00;    /* End of Sector signature */
  698.       newboot[SECTOR_SIZE+0x1FD]=0x00;
  699.       newboot[SECTOR_SIZE+0x1FE]=0x55;
  700.       newboot[SECTOR_SIZE+0x1FF]=0xAA;
  701.       newboot[2*SECTOR_SIZE+0x1FC]=0x00;    /* End of Sector signature */
  702.       newboot[2*SECTOR_SIZE+0x1FD]=0x00;
  703.       newboot[2*SECTOR_SIZE+0x1FE]=0x55;
  704.       newboot[2*SECTOR_SIZE+0x1FF]=0xAA;
  705.       if(check_volume_name(&newboot[FAT32_PART_NAME],11))
  706.     newboot[FAT32_PART_NAME]='\0';
  707.       break;
  708.     default:
  709.       ecrit_rapport("create_fat_boot_sector: severe error\n");
  710.       exit(1);
  711. }
  712.   if(memcmp(newboot,orgboot,1*SECTOR_SIZE))    /* Only compare the first sector */
  713.   {
  714.     ecrit_rapport("             New / Current boot sector");
  715.     dump_2fat_rapport(fat_header,org_fat_header,upart_type);
  716.     ecrit_rapport("Extrapolated boot sector and current boot sector are different.\n");
  717.   }
  718.   else
  719.   {
  720.     ecrit_rapport("Extrapolated boot sector and current boot sector are identical.\n");
  721.   }
  722.   /* */
  723.   if(interface)
  724.   {
  725.     struct MenuItem menuSaveBoot[]=
  726.     {
  727.       { 'D', "Dump", "Dump sector" },
  728.       { 'L', "List", "List directories and files" },
  729.       { 'W', "Write","Write boot"},
  730.       { 'Q',"Quit","Quit this section"},
  731.       { 0, NULL, NULL }
  732.     };
  733.     const char *options="DLQ";
  734.     int do_write=0;
  735.     int do_exit=0;
  736.     do
  737.     {
  738.       do_exit=0;
  739.       aff_copy(stdscr);
  740.       wmove(stdscr,4,0);
  741.       wdoprintf(stdscr,"%s",disk_car->description(disk_car));
  742. /*     mvwaddstr(stdscr,5,0,msg_PART_HEADER2); */
  743.       wmove(stdscr,5,0);
  744.       aff_part(stdscr,AFF_PART_ORDER,disk_car,partition);
  745.       wmove(stdscr,8,0);
  746.       if(memcmp(newboot,orgboot,SECTOR_SIZE))    /* Only compare the first sector */
  747.       {
  748.     options="DLWQ";
  749.     dump_2fat_info(fat_header, org_fat_header, upart_type);
  750.     wdoprintf(stdscr,"Extrapolated boot sector and current boot sector are different.\n");
  751.     if(error)
  752.     {
  753.       wdoprintf(stdscr,"Warning: Extrapolated boot sector have incorrect values.\n");
  754.       ecrit_rapport("Warning: Extrapolated boot sector have incorrect values.\n");
  755.     }
  756.       }
  757.       else
  758.       {
  759.     dump_fat_info(fat_header, upart_type);
  760.     wdoprintf(stdscr,"Extrapolated boot sector and current boot sector are identical.\n");
  761.       }
  762.       switch(toupper(wmenuSelect(stdscr,INTER_DUMP_Y, INTER_DUMP_X, menuSaveBoot,8,options,MENU_HORIZ|MENU_BUTTON|MENU_ACCEPT_OTHERS, 1)))
  763.       {
  764.     case 'W':
  765.       if(strchr(options,'W'))
  766.         do_write=1;
  767.       break;
  768.     case 'D':
  769.       if(strchr(options,'D'))
  770.       {
  771.         dump2(stdscr,newboot,orgboot, upart_type==UP_FAT32?3*SECTOR_SIZE:SECTOR_SIZE);
  772.       }
  773.       break;
  774.     case 'L':
  775.       dir_partition_fat_aux(stdscr,disk_car, partition, debug, fat_header);
  776.       break;
  777.     case 'Q':
  778.       do_exit=1;
  779.       break;
  780.       }
  781.     } while(!do_write && !do_exit);
  782.     if(do_write && ask_confirmation("Write FAT boot sector, confirm ? (Y/N)"))
  783.     {
  784.       int err=0;
  785.       ecrit_rapport("Write new boot!\n");
  786.       /* Write boot sector and backup boot sector */
  787.       if(upart_type==UP_FAT32)
  788.       {
  789.     if(disk_car->write(disk_car,3, &newboot, partition->lba)!=0 ||
  790.         disk_car->write(disk_car,3, &newboot, partition->lba+le16(fat_header->backup_boot))!=0)
  791.       err=1;
  792.       }
  793.       else
  794.       {
  795.     if(disk_car->write(disk_car,1, &newboot, partition->lba)!=0)
  796.       err=1;
  797.       }
  798.       if(err==1)
  799.       {
  800.     display_message("Write error: Can't write new FAT boot sector\n");
  801.       }
  802.       /* TestDisk don't correct the filesystem, use another utility */
  803.     }
  804.     else
  805.       ecrit_rapport("Don't write new boot!\n");
  806.   }
  807.   return 0;
  808. }
  809.  
  810. static int calcul_cluster_size(const upart_type_t upart_type, const dword data_size, const unsigned int fat_length)
  811. {
  812. /* ecrit_rapport("calcul_cluster_size data_size=%lu, fat_length=%u\n",data_size,fat_length); */
  813.   if(fat_length==0)
  814.     return 0;
  815.   switch(upart_type)
  816.   {
  817.     case UP_FAT12:
  818.       return up2power(data_size/(fat_length*SECTOR_SIZE*2/3-1));
  819.     case UP_FAT16:
  820.       return up2power(data_size/(fat_length*SECTOR_SIZE/2-1));
  821.     case UP_FAT32:
  822.       return up2power(data_size/(fat_length*SECTOR_SIZE/4-1));
  823.     default:
  824.       ecrit_rapport("calcul_cluster_size: severe error\n");
  825.       return 0;
  826.   }
  827. }
  828.  
  829. static unsigned int fat_find_fat_start(const unsigned char *buffer,const int p_fat12, const int p_fat16, const int p_fat32,dword*fat_offset)
  830. {
  831.   t_info_offset info_offset[0x200];
  832.   unsigned int nbr_offset=0;
  833.   if(p_fat12!=0)
  834.   {
  835.     unsigned int i;
  836.     int low;
  837.     int high;
  838.     i=0;
  839.     high=0;
  840.     low=0;
  841.     while(high<(SECTOR_SIZE-1))
  842.     {
  843.       dword cluster=0;
  844.       if(low==0)
  845.     cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
  846.       else
  847.     cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
  848.       if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3)%(2*SECTOR_SIZE)==0))
  849.       {
  850.     unsigned int j;
  851.     for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=(cluster-i-1)*3/(2*SECTOR_SIZE))&&(info_offset[j].fat_type==12);j++);
  852.     if(j<nbr_offset)
  853.       info_offset[j].nbr++;
  854.     else
  855.     {
  856.       info_offset[nbr_offset].offset=(cluster-i-1)*3/(2*SECTOR_SIZE);
  857.       info_offset[nbr_offset].nbr=1;
  858.       info_offset[nbr_offset].fat_type=12;
  859.       nbr_offset++;
  860.     }
  861.       }
  862.       if(low==0)
  863.     low=1;
  864.       else
  865.       {
  866.     high++;
  867.     low=0;
  868.       }
  869.       high++;
  870.       i++;
  871.     }
  872.     i=1;
  873.     high=1;
  874.     low=0;
  875.     while(high<(SECTOR_SIZE-1))
  876.     {
  877.       dword cluster=0;
  878.       if(low==0)
  879.     cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
  880.       else
  881.     cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
  882.       if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3+1)%(2*SECTOR_SIZE)==0))
  883.       {
  884.     unsigned int j;
  885.     for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=((cluster-i-1)*3+1)/(2*SECTOR_SIZE))&&(info_offset[j].fat_type==12);j++);
  886.     if(j<nbr_offset)
  887.       info_offset[j].nbr++;
  888.     else
  889.     {
  890.       info_offset[nbr_offset].offset=((cluster-i-1)*3+1)/(2*SECTOR_SIZE);
  891.       info_offset[nbr_offset].nbr=1;
  892.       info_offset[nbr_offset].fat_type=12;
  893.       nbr_offset++;
  894.     }
  895.       }
  896.       if(low==0)
  897.     low=1;
  898.       else
  899.       {
  900.     high++;
  901.     low=0;
  902.       }
  903.       high++;
  904.       i++;
  905.     }
  906.     i=1;
  907.     high=0;
  908.     low=1;
  909.     while(high<(SECTOR_SIZE-1))
  910.     {
  911.       dword cluster=0;
  912.       if(low==0)
  913.     cluster=((buffer[high+1] & 0x0F) <<8) | buffer[high];
  914.       else
  915.     cluster=(buffer[high+1] <<4) | ((buffer[high]&0xF0)>>4);
  916.       if((cluster!=0) && ((cluster&0x0ff8)!=(unsigned)0x0ff8) && (((cluster-i-1)*3+2)%(2*SECTOR_SIZE)==0))
  917.       {
  918.     unsigned int j;
  919.     for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=((cluster-i-1)*3+2)/(2*SECTOR_SIZE))&&(info_offset[j].fat_type==12);j++);
  920.     if(j<nbr_offset)
  921.       info_offset[j].nbr++;
  922.     else
  923.     {
  924.       info_offset[nbr_offset].offset=((cluster-i-1)*3+2)/(2*SECTOR_SIZE);
  925.       info_offset[nbr_offset].nbr=1;
  926.       info_offset[nbr_offset].fat_type=12;
  927.       nbr_offset++;
  928.     }
  929.       }
  930.       if(low==0)
  931.     low=1;
  932.       else
  933.       {
  934.     high++;
  935.     low=0;
  936.       }
  937.       high++;
  938.       i++;
  939.     }
  940.   }
  941.   if(p_fat16!=0)
  942.   {
  943.     unsigned int i,j;
  944.     const word *p16=(const word*)buffer;
  945.     unsigned int err=0;
  946.     for(i=0; (i<SECTOR_SIZE/2)&&(err==0); i++)
  947.     {
  948.       dword cluster=le16(p16[i]);
  949.       if(cluster==1)
  950.       {
  951.     err=1;
  952.       }
  953.       if((cluster!=0) && ((cluster&0x0fff8)!=(unsigned)0x0fff8))
  954.       {
  955.     for(j=i+1; (j<SECTOR_SIZE/2)&&(err==0); j++)
  956.     {
  957.       if(cluster==le16(p16[j]))
  958.       {
  959.         err=1;
  960.       }
  961.     }
  962.       }
  963.     }
  964.     if(err==0)
  965.     {
  966.       for(i=0; i<SECTOR_SIZE/2; i++)
  967.       {
  968.     dword cluster=le16(p16[i]);
  969.     if((cluster!=0) && ((cluster&0x0fff8)!=(unsigned)0x0fff8)&&((cluster-i-1)%(SECTOR_SIZE/2)==0))
  970.     {
  971.       for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=(cluster-i-1)/(SECTOR_SIZE/2))&&(info_offset[j].fat_type==16);j++);
  972.       if(j<nbr_offset)
  973.         info_offset[j].nbr++;
  974.       else
  975.       {
  976.         info_offset[nbr_offset].offset=(cluster-i-1)/(SECTOR_SIZE/2);
  977.         info_offset[nbr_offset].nbr=1;
  978.         info_offset[nbr_offset].fat_type=16;
  979.         nbr_offset++;
  980.       }
  981.     }
  982.       }
  983.     }
  984.   }
  985.   if(p_fat32!=0)
  986.   {
  987.     unsigned int i,j;
  988.     const dword *p32=(const dword*)buffer;
  989.     unsigned int err=0;
  990.     for(i=0; (i<SECTOR_SIZE/4)&&(err==0); i++)
  991.     {
  992.       dword cluster=le32(p32[i])&0x0FFFFFFF;
  993.       if(cluster==1)
  994.       {
  995.     err=1;
  996.       }
  997.       if((cluster!=0) && ((cluster&0x0ffffff8)!=(unsigned)0x0ffffff8))
  998.       {
  999.     for(j=i+1; (j<SECTOR_SIZE/4)&&(err==0); j++)
  1000.     {
  1001.       if(cluster==(le32(p32[j])&0x0FFFFFFF))
  1002.       {
  1003.         err=1;
  1004.       }
  1005.     }
  1006.       }
  1007.     }
  1008.     if(err==0)
  1009.     {
  1010.       for(i=0; i<SECTOR_SIZE/4; i++)
  1011.       {
  1012.     dword cluster=le32(p32[i])&0x0FFFFFFF;
  1013.     if((cluster!=0) && ((cluster&0x0ffffff8)!=(unsigned)0x0ffffff8)&&((cluster-i-1)%(SECTOR_SIZE/4)==0))
  1014.     {
  1015.       for(j=0;(j<nbr_offset)&&(info_offset[j].offset!=(cluster-i-1)/(SECTOR_SIZE/4))&&(info_offset[j].fat_type==32);j++);
  1016.       if(j<nbr_offset)
  1017.         info_offset[j].nbr++;
  1018.       else
  1019.       {
  1020.         info_offset[nbr_offset].offset=(cluster-i-1)/(SECTOR_SIZE/4);
  1021.         info_offset[nbr_offset].nbr=1;
  1022.         info_offset[nbr_offset].fat_type=32;
  1023.         nbr_offset++;
  1024.       }
  1025.     }
  1026.       }
  1027.     }
  1028.   }
  1029.   if(nbr_offset==0)
  1030.       return 0;
  1031.   {
  1032.     unsigned int j;
  1033.     unsigned int best_j=0;
  1034.     for(j=0;j<nbr_offset;j++)
  1035.     {
  1036.       if(info_offset[j].nbr>info_offset[best_j].nbr)
  1037.     best_j=j;
  1038.     }
  1039.     if(info_offset[best_j].nbr>10)
  1040.     {
  1041.       *fat_offset=info_offset[best_j].offset;
  1042.       return info_offset[best_j].fat_type;
  1043.     }
  1044.   }
  1045.   return 0;
  1046. }
  1047.  
  1048. /* TestDisk assumes BPB_media is 0xF8, standard value for fixed disk.
  1049.  * */
  1050.  
  1051.  
  1052. static int fat_find_type(t_param_disk *disk_car,const t_diskext *partition,const dword max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int debug,const int dump_ind,const int interface,unsigned int *nbr_offset,t_info_offset *info_offset)
  1053. {
  1054.   dword offset;
  1055.   dword hd_offset;
  1056.   if(debug)
  1057.     ecrit_rapport("fat_find_type(partition,max_offset=%ld,p_fat12=%d,p_fat16=%d,p_fat32=%d,*f_fat12,*f_fat16,*f_fat32,debug=%d,dump_ind=%d)\n",max_offset,p_fat12,p_fat16,p_fat32,debug,dump_ind);
  1058.   for(offset=1,hd_offset=partition->lba+1;(offset<max_offset)&&(*nbr_offset<0x200);offset++,hd_offset++)
  1059.   {
  1060.     unsigned char buffer[SECTOR_SIZE];
  1061.     if(interface && ((offset&0x1FF)==0))
  1062.     {
  1063.       wmove(stdscr,8,0);
  1064.       wdoprintf(stdscr,"FAT : %s%s%s?\n",p_fat12?"12 ":"", p_fat16?"16 ":"", p_fat32?"32 ":"");
  1065.       wmove(stdscr,8,30);
  1066.       wclrtoeol(stdscr);    /* before addstr for BSD compatibility */
  1067.       wdoprintf(stdscr,"analyse %10lu/%lu",offset,max_offset);
  1068.       wrefresh(stdscr);
  1069.     }
  1070.     if(disk_car->read(disk_car,1, &buffer, hd_offset)!=0)
  1071.     {
  1072.       continue;
  1073.     }
  1074.     {
  1075.       dword fat_offset=0;
  1076.       unsigned int fat_type;
  1077.       fat_type=fat_find_fat_start(buffer,p_fat12,p_fat16,p_fat32,&fat_offset);
  1078.       if(fat_type!=0 && fat_offset<offset)
  1079.       {
  1080.     unsigned int j;
  1081.     if(debug>1)
  1082.     {
  1083.       ecrit_rapport("fat_find_fat_start FAT%u at %lu:%lu\n",fat_type,offset-fat_offset,offset);
  1084.     }
  1085.     for(j=0;(j<*nbr_offset)&&(info_offset[j].offset!=offset-fat_offset)&&(info_offset[j].fat_type==fat_type);j++);
  1086.     if(j<*nbr_offset)
  1087.       info_offset[j].nbr++;
  1088.     else
  1089.     {
  1090.       if(*nbr_offset<0x200)
  1091.       {
  1092.         info_offset[*nbr_offset].offset=offset-fat_offset;
  1093.         info_offset[*nbr_offset].nbr=1;
  1094.         info_offset[*nbr_offset].fat_type=fat_type;
  1095.         (*nbr_offset)++;
  1096.       }
  1097.     }
  1098.       }
  1099.     }
  1100.   }
  1101.   return 0;
  1102. }
  1103.  
  1104. static upart_type_t fat_find_info(t_param_disk *disk_car,unsigned int*reserved, unsigned int*fat_length, const t_diskext *partition,const dword max_offset,const int p_fat12,const int p_fat16,const int p_fat32,const int debug,const int dump_ind,const int interface)
  1105. {
  1106.   unsigned int nbr_offset=0;
  1107.   t_info_offset info_offset[0x200];
  1108.   upart_type_t upart_type=UP_UNK;
  1109.   fat_find_type(disk_car, partition,max_offset,p_fat12,p_fat16,p_fat32,debug,dump_ind,interface,&nbr_offset,&info_offset[0]);
  1110.   {
  1111.     unsigned int i;
  1112.     for(i=0;i<nbr_offset;i++)
  1113.     {
  1114.       ecrit_rapport("FAT%u at %lu(%u/%u/%u), nbr=%u\n",info_offset[i].fat_type,info_offset[i].offset,
  1115.       LBA2cylinder(disk_car,partition->lba+info_offset[i].offset),
  1116.       LBA2head(disk_car,partition->lba+info_offset[i].offset),
  1117.       LBA2sector(disk_car,partition->lba+info_offset[i].offset), info_offset[i].nbr);
  1118.       if((dump_ind>0) && (interface>0))
  1119.       {
  1120.     unsigned char buffer[SECTOR_SIZE];
  1121.     if(disk_car->read(disk_car,1, &buffer, partition->lba+info_offset[i].offset)==0)
  1122.     {
  1123.       dump(stdscr,buffer,SECTOR_SIZE);
  1124.     }
  1125.       }
  1126.     }
  1127.   }
  1128.   if(nbr_offset>0)
  1129.   {
  1130.     switch(info_offset[0].fat_type)
  1131.     {
  1132.       case 12: upart_type=UP_FAT12; break;
  1133.       case 16: upart_type=UP_FAT16; break;
  1134.       case 32: upart_type=UP_FAT32; break;
  1135.     }
  1136.   }
  1137.   switch(nbr_offset)
  1138.   {
  1139.     case 0:
  1140.       *fat_length=0;
  1141.       break;
  1142.     case 1:
  1143.       switch(upart_type)
  1144.       {
  1145.     case UP_FAT12:
  1146.     case UP_FAT16:
  1147.       *reserved=1;
  1148.       if(info_offset[0].offset>*reserved)
  1149.         *fat_length=info_offset[0].offset-*reserved;
  1150.       else
  1151.         *fat_length=0;
  1152.       break;
  1153.     case UP_FAT32:
  1154.       if(info_offset[0].offset==32 || info_offset[0].offset==33)
  1155.         *reserved=info_offset[0].offset;
  1156.       *fat_length=0;
  1157.       break;
  1158.     default:
  1159.       ecrit_rapport("fat_find_info: severe error\n");
  1160.       return UP_UNK;
  1161.       }
  1162.       break;
  1163.     default:
  1164.       switch(upart_type)
  1165.       {
  1166.     case UP_FAT12:
  1167.     case UP_FAT16:
  1168.       *reserved=1;
  1169.       if(info_offset[0].offset==*reserved)
  1170.         *fat_length=info_offset[1].offset-info_offset[0].offset;
  1171.       else
  1172.         *fat_length=info_offset[0].offset-*reserved;
  1173.       break;
  1174.     case UP_FAT32:
  1175.         *reserved=info_offset[0].offset;
  1176.         *fat_length=info_offset[1].offset-info_offset[0].offset;
  1177.       if(*reserved==32 || *reserved==33 || comp_FAT(disk_car,partition,*fat_length,*reserved)==0)
  1178.       {
  1179.       } else {
  1180.         *reserved=0;
  1181.         *fat_length=0;
  1182.       }
  1183.       break;
  1184.     default:
  1185.       ecrit_rapport("fat_find_info: severe error\n");
  1186.       return UP_UNK;
  1187.       }
  1188.       break;
  1189.   }
  1190.   return upart_type;
  1191. }
  1192.  
  1193. /* Using a couple of inodes of "." directory entries, get the cluster size and where the first cluster begins.
  1194.  * */
  1195. static int find_cluster_size(t_param_disk *disk_car, t_diskext *partition, const int debug, const int dump_ind,const int interface, unsigned int *cluster_size, dword *offset)
  1196. {
  1197.   dword i;
  1198.   dword skip_sector;
  1199.   unsigned char buffer[SECTOR_SIZE];
  1200.   int ind_stop=FALSE;
  1201.   unsigned int nbr_subdir=0;
  1202.   t_sector_cluster sector_cluster[10];
  1203.  
  1204.   if(interface)
  1205.   {
  1206.     wmove(stdscr,22,0);
  1207.     wstandout(stdscr);
  1208.     waddstr(stdscr,"  Stop  ");
  1209.     wstandend(stdscr);
  1210.   }
  1211.   /* 2 fats, maximum cluster size=128 */
  1212.   skip_sector=(partition->part_size-32)/128*1.5/SECTOR_SIZE*2;
  1213.   ecrit_rapport("find_cluster_size skip_sector=%lu\n",skip_sector);
  1214.   for(i=skip_sector;(i<partition->part_size)&&!ind_stop&&(nbr_subdir<10);i++)
  1215.   {
  1216.     if(interface && ((i&0x1FF)==0))
  1217.     {
  1218.       wmove(stdscr,9,0);
  1219.       wclrtoeol(stdscr);
  1220.       wdoprintf(stdscr,"Search subdirectory %10lu/%lu %u",i,partition->part_size,nbr_subdir);
  1221.       wrefresh(stdscr);
  1222.       switch(wgetch_nodelay(stdscr))
  1223.       {
  1224.     case KEY_ENTER:
  1225. #ifdef PADENTER
  1226.     case PADENTER:
  1227. #endif
  1228.     case '\n':
  1229.     case '\r':
  1230.     case 's':
  1231.     case 'S':
  1232.       ind_stop=1;
  1233.       break;
  1234.       }
  1235.     }
  1236.     if(disk_car->read(disk_car,1, &buffer, partition->lba+i)==0)
  1237.     {
  1238.       if((memcmp(&buffer[0],".          ",8+3)==0)&&(memcmp(&buffer[0x20],"..         ",8+3)==0))
  1239.       {
  1240.     dword cluster=(buffer[0*0x20+0x15]<<24)+(buffer[0*0x20+0x14]<<16)+
  1241.       (buffer[0*0x20+0x1B]<<8)+buffer[0*0x20+0x1A];
  1242.     ecrit_rapport("sector %lu, cluster %lu\n",i,cluster);
  1243.     sector_cluster[nbr_subdir].cluster=cluster;
  1244.     sector_cluster[nbr_subdir].sector=i;
  1245.     nbr_subdir++;
  1246.       }
  1247.     }
  1248.   }
  1249.   return find_cluster_size_aux(sector_cluster,nbr_subdir,cluster_size,offset,debug);
  1250. }
  1251.  
  1252. static int find_cluster_size_aux(const t_sector_cluster *sector_cluster, const unsigned int nbr_sector_cluster,unsigned int *cluster_size, dword *offset, const int debug)
  1253. {
  1254.   if(nbr_sector_cluster<2)
  1255.     return 0;
  1256.   {
  1257.     unsigned int i,j;
  1258.     unsigned int nbr_sol=0;
  1259.     t_cluster_offset cluster_offset[nbr_sector_cluster*nbr_sector_cluster];
  1260.     for(i=0;i<nbr_sector_cluster-1;i++)
  1261.     {
  1262.       for(j=i+1;j<nbr_sector_cluster;j++)
  1263.       {
  1264.     if(sector_cluster[j].cluster>sector_cluster[i].cluster)
  1265.     {
  1266.       unsigned int cluster_size_tmp=(sector_cluster[j].sector-sector_cluster[i].sector)/(sector_cluster[j].cluster-sector_cluster[i].cluster);
  1267.       switch(cluster_size_tmp)
  1268.       {
  1269.         case 1:
  1270.         case 2:
  1271.         case 4:
  1272.         case 8:
  1273.         case 16:
  1274.         case 32:
  1275.         case 64:
  1276.         case 128:
  1277.           if(sector_cluster[i].sector>(sector_cluster[i].cluster-2)*(*cluster_size))
  1278.           {
  1279.         unsigned int sol_cur;
  1280.         unsigned int found=0;
  1281.         unsigned int offset_tmp=sector_cluster[i].sector-(sector_cluster[i].cluster-2)*cluster_size_tmp;
  1282.         for(sol_cur=0;(sol_cur<nbr_sol)&&!found;sol_cur++)
  1283.         {
  1284.           if(cluster_offset[sol_cur].cluster_size==cluster_size_tmp &&
  1285.               cluster_offset[sol_cur].offset==offset_tmp)
  1286.           {
  1287.             if(cluster_offset[sol_cur].first_sol==i)
  1288.             {
  1289.               cluster_offset[sol_cur].nbr++;
  1290.             }
  1291.             /*        ecrit_rapport("cluster_size=%u offset=%lu nbr=%u\n",cluster_offset[sol_cur].cluster_size,cluster_offset[sol_cur].offset,cluster_offset[sol_cur].nbr); */
  1292.             found=1;
  1293.           }
  1294.         }
  1295.         if(!found)
  1296.         {
  1297.           cluster_offset[nbr_sol].cluster_size=cluster_size_tmp;
  1298.           cluster_offset[nbr_sol].offset=offset_tmp;
  1299.           cluster_offset[nbr_sol].nbr=1;
  1300.           cluster_offset[nbr_sol].first_sol=i;
  1301.           nbr_sol++;
  1302.         }
  1303.           }
  1304.           break;
  1305.       }
  1306.     }
  1307.       }
  1308.     }
  1309.     /* Show results */
  1310.     {
  1311.       unsigned int nbr_max=0;
  1312.       unsigned int sol_cur;
  1313.       for(sol_cur=0;sol_cur<nbr_sol;sol_cur++)
  1314.       {
  1315.     if(debug>0)
  1316.       ecrit_rapport("cluster_size=%u offset=%lu nbr=%u\n",cluster_offset[sol_cur].cluster_size,cluster_offset[sol_cur].offset,cluster_offset[sol_cur].nbr);
  1317.     if(cluster_offset[sol_cur].nbr>nbr_max)
  1318.     {
  1319.       nbr_max=cluster_offset[sol_cur].nbr;
  1320.       *cluster_size=cluster_offset[sol_cur].cluster_size;
  1321.       *offset=cluster_offset[sol_cur].offset;
  1322.     }
  1323.       }
  1324.       if(nbr_max>0)
  1325.       {
  1326.     ecrit_rapport("Selected: cluster_size=%u offset=%lu nbr=%u\n",*cluster_size, *offset,nbr_max);
  1327.     return 1;
  1328.       }
  1329.     }
  1330.   }
  1331.   /* Failed */
  1332.   return 0;
  1333. }
  1334.  
  1335.  
  1336. int rebuild_FAT_BS(t_param_disk *disk_car, t_diskext *partition, const int debug, const int dump_ind,const int interface)
  1337. {
  1338.   dword start_data=0;
  1339.   dword data_size;
  1340.   unsigned int fat_length=0;
  1341.   dword fat_length_max;
  1342.   int p_fat12,p_fat16,p_fat32;
  1343.   unsigned int cluster_size_min=1;
  1344.   unsigned int cluster_size=0;
  1345.   dword max_offset;
  1346.   dword root_cluster=0;    /* Initialized by fat32_find_root_cluster */
  1347.   int upart_type;
  1348.   unsigned int dir_entries=0;
  1349.   unsigned int reserved=0;
  1350.   /* Initialized by fat32_free_info */
  1351.   dword free_count=0;
  1352.   dword next_free=0;
  1353.   /*
  1354.    * Using partition size, check if partition can be FAT12, FAT16 or FAT32
  1355.    * */
  1356.   if(partition->part_size>(2*1024+1)*1024*2)
  1357.   {
  1358.     p_fat32=1;
  1359.     p_fat16=0;
  1360.     p_fat12=0;
  1361.   }
  1362.   else
  1363.     /* 1<<12 clusters * 8 secteurs/clusters= 32768 secteurs 
  1364.        fat_length=((1<<12+1)*1.5/SECTOR_SIZE)+1=13; */
  1365.     if(partition->part_size>=(1+2*13+32768+63))
  1366.     {
  1367.       p_fat32=1;
  1368.       p_fat16=1;
  1369.       p_fat12=0;
  1370.     }
  1371.     else
  1372.     {
  1373.       p_fat32=0;
  1374.       p_fat16=1;
  1375.       p_fat12=1;
  1376.     }
  1377. #ifdef TESTING
  1378.   p_fat32=1; p_fat16=1; p_fat12=1;
  1379. #endif
  1380.   if(debug)
  1381.   {
  1382.     ecrit_rapport("\n");
  1383.     aff_part_rapport(disk_car,partition);
  1384.     ecrit_rapport("rebuild_FAT_BS p_fat12 %d, p_fat16 %d, p_fat32 %d\n", p_fat12,p_fat16,p_fat32);
  1385.   }
  1386.   /* Set fat_length_max */
  1387.   if(p_fat32)
  1388.   {    /* Cluster 1k */
  1389.     fat_length_max=partition->part_size/cluster_size_min*4/SECTOR_SIZE;
  1390.   }
  1391.   else
  1392.     if(p_fat16)
  1393.     {
  1394.       while(partition->part_size/cluster_size_min>(1<<16))
  1395.     cluster_size_min*=2;
  1396.       fat_length_max=partition->part_size/cluster_size_min*2/SECTOR_SIZE;
  1397.     }
  1398.     else
  1399.     {
  1400.       while(partition->part_size/cluster_size_min>(1<<12))
  1401.     cluster_size_min*=2;
  1402.       fat_length_max=partition->part_size/cluster_size_min*1.5/SECTOR_SIZE;
  1403.     }
  1404.   if(debug)
  1405.   {
  1406.     ecrit_rapport("cluster_size_min %u\n",cluster_size_min);
  1407.     ecrit_rapport("fat_length_max %ld\n", fat_length_max);
  1408.   }
  1409.   max_offset=fat_length_max+64;
  1410.   /*
  1411.      if(debug)
  1412.      ecrit_rapport("search_fat16(partition,max_offset=%d,p_fat12=%d,p_fat16=%d,p_fat32=%d,debug=%d,dump_ind=%d)\n",max_offset,p_fat12,p_fat16,p_fat32,debug,dump_ind);
  1413.    */
  1414.   if(interface)
  1415.   {
  1416.     aff_copy(stdscr);
  1417.     wmove(stdscr,4,0);
  1418.     wdoprintf(stdscr,"%s",disk_car->description(disk_car));
  1419. /*   mvwaddstr(stdscr,5,0,msg_PART_HEADER2); */
  1420.     wmove(stdscr,5,0);
  1421.     aff_part(stdscr,AFF_PART_ORDER,disk_car,partition);
  1422.     wrefresh(stdscr);
  1423.   }
  1424.   upart_type=fat_find_info(disk_car,&reserved, &fat_length, partition,max_offset,p_fat12,p_fat16,p_fat32,debug,dump_ind,interface);
  1425.   if(interface)
  1426.   {
  1427.     wmove(stdscr,8,0);
  1428.     wclrtoeol(stdscr);
  1429.     switch(upart_type)
  1430.     {
  1431.       case UP_FAT12:
  1432.     waddstr(stdscr,"FAT : 12");
  1433.     break;
  1434.       case UP_FAT16:
  1435.     waddstr(stdscr,"FAT : 16");
  1436.     break;
  1437.       case UP_FAT32:
  1438.     waddstr(stdscr,"FAT : 32");
  1439.     break;
  1440.       default:
  1441.     waddstr(stdscr,"No FAT found");
  1442.     break;
  1443.     }
  1444.   }
  1445.   if((upart_type!=UP_FAT12 && upart_type!=UP_FAT16 && upart_type!=UP_FAT32)||
  1446.       (fat_length==0)||(reserved==0))
  1447.   {
  1448.     if(find_cluster_size(disk_car, partition, debug, dump_ind, interface,&cluster_size,&start_data)==0)
  1449.     {
  1450.       ecrit_rapport("Can't find cluster size\n");
  1451.       return 0;
  1452.     }
  1453.     if((cluster_size<=0) || (partition->part_size<=start_data))
  1454.     {
  1455.       ecrit_rapport("Can't find cluster size\n");
  1456.       return 0;
  1457.     }
  1458.     {
  1459.       unsigned int no_of_cluster;
  1460.       no_of_cluster=(partition->part_size-start_data)/cluster_size;
  1461.       if(no_of_cluster<65525)
  1462.       {
  1463.     if(no_of_cluster<4085)
  1464.     { /* FAT12 */
  1465.       ecrit_rapport("FAT : 12\n");
  1466.       upart_type=UP_FAT12;
  1467.     }
  1468.     else
  1469.     { /* FAT16 */
  1470.       ecrit_rapport("FAT : 16\n");
  1471.       upart_type=UP_FAT16;
  1472.     }
  1473.     reserved=1;        /* must be 1 */
  1474.     dir_entries=find_dir_entries(disk_car,partition,start_data-1,debug);
  1475.     switch(dir_entries)
  1476.     {
  1477.       case 0:
  1478.         ecrit_rapport("dir_entries not found, should be 512\n");
  1479.         dir_entries=512;
  1480.         break;
  1481.       case 512:
  1482.         if(debug)
  1483.           ecrit_rapport("dir_entries: %u\n",dir_entries);
  1484.         break;
  1485.       default:
  1486.         ecrit_rapport("dir_entries: %u (unusual value)\n",dir_entries);
  1487.         break;
  1488.     }
  1489.     fat_length=(start_data-reserved-((dir_entries-1)/16+1))/2;
  1490.     if(debug)
  1491.       ecrit_rapport("fat_length %u\n",fat_length);
  1492.       }
  1493.       else
  1494.       { /* FAT32*/
  1495.     ecrit_rapport("FAT : 32\n");
  1496.     upart_type=UP_FAT32;
  1497.     reserved=32;
  1498.     if((start_data&1)!=0)
  1499.       reserved+=1;
  1500.     fat_length=(start_data-reserved)/2;      
  1501.       }
  1502.       if(debug)
  1503.     ecrit_rapport("fat_length %u\n",fat_length);
  1504.     }
  1505.   }
  1506.   if(interface)
  1507.   {
  1508.     if(fat_length==0)
  1509.       waddstr(stdscr," Can't find FAT length\n");
  1510.     wrefresh(stdscr);
  1511.   }
  1512.   if(upart_type && (fat_length>1))
  1513.   {
  1514.     start_data=reserved+2*fat_length;
  1515.     /* FAT1x: Find size of root directory */
  1516.     if((upart_type==UP_FAT12) || (upart_type==UP_FAT16))
  1517.     {
  1518.       int old_dir_entries=dir_entries;
  1519.       dir_entries=analyse_dir_entries(disk_car,partition,reserved+2*fat_length,debug);
  1520.       ecrit_rapport("dir_entries %u\n",dir_entries);
  1521.       dir_entries=analyse_dir_entries2(disk_car,partition,reserved,fat_length,debug,dir_entries,upart_type);
  1522.       ecrit_rapport("dir_entries %u\n",dir_entries);
  1523.       if(dir_entries==0)
  1524.       {
  1525.     if(old_dir_entries>0)
  1526.       fat_length=0;
  1527.     /*
  1528.     else
  1529.     {
  1530.       dir_entries=512;
  1531.       ecrit_rapport("analyse_dir_entries: use default dir_entries %u\n",dir_entries);
  1532.     }
  1533.     */
  1534.       }
  1535.       start_data+=(dir_entries+16-1)/16;
  1536.     }
  1537.     if(partition->part_size<=start_data)
  1538.     {
  1539.       ecrit_rapport("Error part_size=%lu <= start_data=%lu\n",partition->part_size,start_data);
  1540.       return 0;
  1541.     }
  1542.     data_size=partition->part_size-start_data;
  1543.     /* Get Cluster Size */
  1544.     {
  1545.       int old_cluster_size=cluster_size;
  1546.       cluster_size=calcul_cluster_size(upart_type,data_size,fat_length);
  1547.       if(debug)
  1548.     ecrit_rapport("cluster_size %u\n",cluster_size);
  1549.       if((cluster_size<=0)||(cluster_size>128))
  1550.       {
  1551.     if(old_cluster_size>0)
  1552.     {
  1553.       cluster_size=old_cluster_size;
  1554.       ecrit_rapport("Assumes previous cluster size was good\n");
  1555.     }
  1556.     else
  1557.     {
  1558.       ecrit_rapport("Can't get cluster size\n");
  1559.       return 0;
  1560.     }
  1561.       }
  1562.     } 
  1563.     if(upart_type==UP_FAT32)
  1564.     {
  1565.       /* Use first fat */
  1566.       fat32_free_info(disk_car,partition,reserved,data_size/cluster_size,&next_free,&free_count);
  1567.       /* FAT32 : Find root cluster */
  1568.       root_cluster=fat32_find_root_cluster(disk_car,partition,cluster_size,data_size/cluster_size,start_data,reserved,interface,debug);
  1569.       /*
  1570.       if(debug>1)
  1571.       {
  1572.     ecrit_rapport("override root_cluster=2\n");
  1573.     root_cluster=2;
  1574.       }
  1575.       */
  1576.     }
  1577.     if(interface)
  1578.     {
  1579.       wmove(stdscr,9,0);
  1580.       wclrtoeol(stdscr);
  1581.       wrefresh(stdscr);
  1582.     }
  1583.     create_fat_boot_sector(disk_car,partition, reserved, debug,dir_entries,root_cluster,cluster_size,fat_length,interface,upart_type);
  1584.     if(debug)
  1585.     {
  1586.       ecrit_rapport("\n");
  1587.       aff_part_rapport(disk_car,partition);
  1588.     }
  1589.   }
  1590.   return 0;
  1591. }
  1592.  
  1593. static int write_FAT_boot_code_aux(unsigned char *buffer)
  1594. {
  1595.   const unsigned char boot_code[SECTOR_SIZE]= {
  1596.     0xeb, 0x3c, 0x90, 0x6d, 0x6b, 0x64, 0x6f, 0x73, 0x66, 0x73, 0x00, 0x00, 0x02, 0x08, 0x01, 0x00,
  1597.     0x02, 0x00, 0x02, 0x00, 0x00, 0xf8, 0xcc, 0x00, 0x3f, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
  1598.     0x5a, 0x5f, 0x06, 0x00, 0x00, 0x00, 0x29, 0xf8, 0x3f, 0x7c, 0x3e, 'T',   'E',   'S', 'T',  'D',
  1599.      'I',  'S',  'K', 0x20, 0x20, 0x20, 0x46, 0x41, 0x54, 0x31, 0x36, 0x20, 0x20, 0x20, 0x0e, 0x1f,
  1600.     0xbe, 0x5b, 0x7c, 0xac, 0x22, 0xc0, 0x74, 0x0b, 0x56, 0xb4, 0x0e, 0xbb, 0x07, 0x00, 0xcd, 0x10,
  1601.     0x5e, 0xeb, 0xf0, 0x32, 0xe4, 0xcd, 0x16, 0xcd, 0x19, 0xeb, 0xfe,  'T', 'h',   'i',  's',  ' ',
  1602.      'i',  's',  ' ',  'n',  'o',  't',  ' ',  'a',  ' ',  'b',  'o',  'o',  't',  'a',  'b',  'l',
  1603.      'e',  ' ',  'd',  'i',  's',  'k',  '.',  ' ',  ' ',  'P',  'l',  'e',  'a',  's',  'e',  ' ',
  1604.      'i',  'n',  's',  'e',  'r',  't',  ' ',  'a',  ' ',  'b',  'o',  'o',  't',  'a',  'b',  'l',
  1605.      'e',  ' ',  'f',  'l',  'o',  'p',  'p',  'y',  ' ',  'a',  'n',  'd', 0x0d, 0x0a,  'p',  'r',
  1606.      'e',  's',  's',  ' ',  'a',  'n',  'y',  ' ',  'k',  'e',  'y',  ' ',  't',  'o',  ' ',  't',
  1607.      'r', 'y',   ' ',  'a',  'g',  'a',  'i',  'n',  ' ',  '.',  '.',  '.',  ' ', 0x0d, 0x0a, 0x00,
  1608.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1609.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1610.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1611.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1612.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1613.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1614.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1615.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1616.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1617.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1618.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1619.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1620.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1621.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1622.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1623.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1624.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1625.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1626.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1627.     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
  1628.   };
  1629.   memcpy(buffer,&boot_code,SECTOR_SIZE);
  1630.   return 0;
  1631. }
  1632.